#include <QtNetwork/QtNetwork>
#include <QtNetwork/QTcpSocket>
#include "openaccountdataaccess.h"
#include "common/dynobjectfactory.h"
#include "common/jinstream.h"
#include "control/bankexception.h"

#define OPEN_ACCOUNT    0x02
#define BUF_SIZE    1024

OpenAccountDataAccess::OpenAccountDataAccess()
{
    data_ = new char[BUF_SIZE];
}

OpenAccountDataAccess::~OpenAccountDataAccess()
{
    delete []data_;
}

//数据进行请求发送
bool OpenAccountDataAccess::requestData(QSharedPointer<QTcpSocket> &cliPipe,
                                        map<QString,QString> &rDataMap)
{
    //按照自己定义的格式进行寻找
    // 包头命令
    quint16 cmd = OPEN_ACCOUNT;
    jos_.Clear();
    jos_ << cmd;

    // 预留两个字节包头len（包体+包尾长度）
    size_t lengthPos = jos_.Length();
    jos_.Skip(2);
    // 客户姓名
    map<QString,QString>::const_iterator it = rDataMap.find("name");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute name can't be found!"));
        return false;
    }
    jos_<< it->second.toStdString();
    // 帐号密码
    it = rDataMap.find("pass");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute pass can't be found!"));
        return false;
    }
    QString pass = it->second;
    encryPassword(pass,cmd);
    //身份证ID（char 18个字节）
    it = rDataMap.find("id");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute id can't be found!"));
        return false;
    }
    QString idStr = it->second;
    const char *idData = (const char *)idStr.toLocal8Bit();
    jos_.WriteBytes(idData,idStr.length());
    //金额（string）
    it = rDataMap.find("cash");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute cash can't be found!"));
        return false;
    }
    jos_ << it->second.toStdString();
    // 包头len
    size_t tailPos = jos_.Length();
    jos_.Reposition(lengthPos);
    jos_<< static_cast<uint16>(tailPos + 8 - sizeof(RequestHead)); // 包体长度 + 包尾长度
    // 包尾
    jos_.Reposition(tailPos);
    // 计算包尾
    generatePackTailMd5(cmd);
    cliPipe->write(jos_.Data(), jos_.Length());
    if(!cliPipe->waitForBytesWritten(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    return true;
}

//对数据进行响应
bool OpenAccountDataAccess::responseData(QSharedPointer<QTcpSocket> &cliPipe,
                                            map<QString, QString> &rDataMap)
{
    memset(data_,0,BUF_SIZE);
    if(!cliPipe->waitForReadyRead(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    dataLen_ = cliPipe->read(data_,BUF_SIZE);
    //这里应该执行接收包的包验证
    if(!checkData()) {
        throw BankException("data check sum error!");
    }
    JInStream jis((const char*)data_, dataLen_);
    // 跳过cmd、len
    jis.Skip(4);
    uint16 cnt;
    uint16 seq;
    int16 error_code;
    jis >> cnt >> seq >> error_code;

    char error_msg[31];
    memset(error_msg,0,sizeof(error_msg));
    jis.ReadBytes(error_msg, 30);

    if(0 != error_code) {
        rDataMap.insert(make_pair("errorMsg",error_msg));
        return false;
    }
    char accountId[7] = {0};
    memset(accountId,0,sizeof(accountId));
    jis.ReadBytes(accountId,6);
    string openDate;
    jis >> openDate;
    rDataMap.insert(make_pair("resAccountId",accountId));
    rDataMap.insert(make_pair("resOpenDate",openDate.c_str()));
    return true;
}

REGISTER_CLASS(OpenAccountDataAccess);
